﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using SerialPortComm;
using Model;
using Telerik.WinControls.UI;
using SerialPortBll;

namespace 串口调试助手
{
    public partial class MainFrm : Form
    {
        #region 属性变量
        public static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public MainFrm()
        {
            InitializeComponent();
        }
        int sendBytes = 0;
        int recvBytes = 0;
        /// <summary>
        /// 获取或设置发送字节数
        /// </summary>
        protected int SEND_BYTES
        {
            get
            {
                return sendBytes;
            }
            set
            {
                sendBytes = value;
                toolStripStatusLabel_sendBytes.Text = String.Format("发送：{0:N0} Bytes", value); //+ " Bytes"; ;
            }
        }

        /// <summary>
        /// 获取或设置接收字节数
        /// </summary>
        protected int RECV_BYTES
        {
            get { return recvBytes; }
            set
            {
                recvBytes = value;
                string rcvTxt = String.Format("接收：{0:N0} Bytes", value); //"接收：" + value+" Bytes";
                if (statusStrip1.InvokeRequired)
                {
                    this.Invoke(new Action<String>(a =>
                    {
                        toolStripStatusLabel_receiveBytes.Text = a;
                    }), rcvTxt);
                }
                else
                {
                    toolStripStatusLabel_receiveBytes.Text = rcvTxt;
                }
            }
        }

        private Timer timer;

        #endregion

        private void MainFrm_Load(object sender, EventArgs e)
        {
            initDeviceConfig();
            initMultiColumnComboBoxData();
            timer = new Timer();
            int times = 1000;
            int.TryParse(toolStripComboBox_sendTimes.Text, out times);
            timer.Interval = times;
            timer.Tick += Timer_Tick;
         
            this.radMultiColumnComboBox1.MultiColumnComboBoxElement.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            radMultiColumnComboBox1.MultiColumnComboBoxElement.DropDownMinSize = new Size(580, 130);
            // this.radMultiColumnComboBox1.AutoSizeDropDownToBestFit = true;
            radMultiColumnComboBox1.MultiColumnComboBoxElement.AutoSizeMode = Telerik.WinControls.RadAutoSizeMode.FitToAvailableSize;
            // radMultiColumnComboBox1.MultiColumnComboBoxElement.DropDownSizingMode = SizingMode.UpDownAndRightBottom;
            //this.radMultiColumnComboBox1.AutoSizeDropDownToBestFit = false; 
            radMultiColumnComboBox1.HorizontalScroll.Enabled = true;
            //radMultiColumnComboBox1.MultiColumnComboBoxElement.BestFitColumns();
            InitMultiComboxSize();
        }

        private void InitMultiComboxSize()
        {
            RadMultiColumnComboBoxElement multiColumnComboElement = this.radMultiColumnComboBox1.MultiColumnComboBoxElement;
          
            multiColumnComboElement.DropDownMaxSize = new Size(radMultiColumnComboBox1.Size.Width, this.Size.Height);
            multiColumnComboElement.Size = new Size(radMultiColumnComboBox1.Size.Width, multiColumnComboElement.Size.Height);
            //multiColumnComboElement.DropDownSizingMode = SizingMode.UpDownAndRightBottom;
            //multiColumnComboElement.DropDownWidth = radMultiColumnComboBox1.Size.Width;
        }

        private void MainFrm_SizeChanged(object sender, EventArgs e)
        {
            InitMultiComboxSize();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            sendData();
        }
        /// <summary>
        /// 初始化设备配置
        /// </summary>
        private void initDeviceConfig()
        {
            string[] portNames = SerialPort.GetPortNames();
            comboBox_portName.Items.Clear();
            comboBox_portName.Items.AddRange(portNames);
            if (comboBox_portName.Items.Count > 0)
            {
                comboBox_portName.Text = comboBox_portName.Items[0].ToString();
            }
            comboBox_boadRate.Text = "9600";
            comboBox_varyBit.Text = "NONE";
            comboBox_StopBit.Text = "1";
            comboBox_DataBit.Text = "8";             
        }

        private void initMultiColumnComboBoxData()
        {
            List<SendDataLog> lst = SendDataLogBMO.getAll();
            //radDropDownList_sendLog.Items.Clear();
            /*
            foreach (var obj in lst)
            {
                Telerik.WinControls.UI.RadListDataItem item = new Telerik.WinControls.UI.RadListDataItem();
                item.Text = obj.Send_name;
                item.Value = obj.Send_data_content;
                item.Tag = obj;
                
            }*/

            // multiColumnComboElement.EditorControl.MasterTemplate.AutoGenerateColumns = false;
            DataTable tbl = new DataTable();
            tbl.Columns.Add("名称");
            tbl.Columns.Add("发送内容");
            tbl.Columns.Add("分组");
            tbl.Columns.Add("模式");
            foreach (var v in lst)
            {
                DataRow r = tbl.NewRow();
                r[0] = v.Send_name;
                r[1] = v.Send_data_content;
                r[2] = v.WorkGroup.Group_name;
                r[3] = v.Send_mode;
                tbl.Rows.Add(r);
            }
            radMultiColumnComboBox1.DataSource = tbl;
            radMultiColumnComboBox1.DisplayMember = "名称";
            radMultiColumnComboBox1.Columns[0].Width = 100;
            radMultiColumnComboBox1.Columns[1].Width = 500;
            radMultiColumnComboBox1.Columns[3].IsVisible = false;
            //radMultiColumnComboBox1.Columns[1].HeaderText = "名称";
            //radMultiColumnComboBox1.Columns[2].HeaderText = "模式";
            //radMultiColumnComboBox1.Columns[2].IsVisible = false;
            ////radMultiColumnComboBox1.Columns[2].FormatString = "发送模式{0}";
            //radMultiColumnComboBox1.Columns[3].HeaderText = "发送内容";
            ////radMultiColumnComboBox1.Columns[3].AutoSizeMode = Telerik.WinControls.UI.BestFitColumnMode.AllCells;//.DisplayedDataCells;
            //// radMultiColumnComboBox1.
            ////radMultiColumnComboBox1.Columns[4].HeaderText = "创建时间";
            //radMultiColumnComboBox1.Columns[4].IsVisible = false;
            //radMultiColumnComboBox1.Columns[5].IsVisible = false;
            //radMultiColumnComboBox1.Columns[6].IsVisible = false;
            //radMultiColumnComboBox1.Columns[7].IsVisible = false;
            //radMultiColumnComboBox1.Columns[8].IsVisible = false;//.HeaderText = "分组";

            // radMultiColumnComboBox1.Dock = DockStyle.Fill 
        }

        private bool OpenSerialPort()
        {
            if (serialPort1 == null)
            {
                return false;
            }
            if (comboBox_portName.Text == null || String.IsNullOrEmpty(comboBox_portName.Text))
            {
                return false;
            }
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
            }
            serialPort1.PortName = comboBox_portName.SelectedItem.ToString();
            int defaultBaurate = 9600;
            if (!int.TryParse(comboBox_boadRate.Text, out defaultBaurate))
            {
                comboBox_boadRate.Text = defaultBaurate.ToString();
            }
            serialPort1.BaudRate = defaultBaurate;

            int dataBit = 8;
            int.TryParse(comboBox_DataBit.Text, out dataBit);
            serialPort1.DataBits = dataBit;

            switch (comboBox_varyBit.Text)
            {
                case "NONE":
                    serialPort1.Parity = Parity.None;
                    break;
                case "EVEN":
                    serialPort1.Parity = Parity.Even;
                    break;
                case "MARK":
                    serialPort1.Parity = Parity.Mark;
                    break;
                case "ODD":
                    serialPort1.Parity = Parity.Odd;
                    break;
                case "SPACE":
                    serialPort1.Parity = Parity.Space;
                    break;
                default:
                    serialPort1.Parity = Parity.None;
                    break;
            }

            try
            {
                serialPort1.Open();
                button_OpenPort.Text = "断开";
                return true;
            }
            catch(Exception ex)
            {
                button_OpenPort.Text = "打开";
                log.Error("串口【" + serialPort1.PortName+"】无法打开，发生异常：{0}",ex);
                return false;
            }
        }


        private void button_OpenPort_Click(object sender, EventArgs e)
        {
            if ("打开".Equals(button_OpenPort.Text))
            {//关闭
                if (OpenSerialPort())
                {
                    button_OpenPort.Text = "断开";
                }
            }
            else
            {
                serialPort1.Close();
                if (!serialPort1.IsOpen)
                {
                    button_OpenPort.Text = "打开";
                }
            }
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (toolStripButton_pause.Checked)
            {
                serialPort1.ReadExisting();
                return;
            }
            int len = serialPort1.BytesToRead;
            byte[] buffer = new byte[len];
            serialPort1.Read(buffer, 0, len);

            RECV_BYTES += len;

            string value;
            if (toolStripButton_HexMod.Checked)
            {
                value = CommonHelper.HexToStr(buffer);
            }
            else
            {
                value = ASCIIEncoding.UTF8.GetString(buffer, 0, len);
            }
            if (toolStripButton_showTime.Checked)
            {
                value = "【" + DateTime.Now.ToString() + "】" + value + "\n";
            }
            else
            {
                value += " ";
            }
            if (richTextBox_Receive.InvokeRequired)
            {
                richTextBox_Receive.Invoke(
                    new Action<string>((v) =>
                    {
                        richTextBox_Receive.AppendText(v);
                    }), value);
            }
            else
            {
                richTextBox_Receive.AppendText(value);
            }
        }

        private void serialPort1_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {

        }

        private void serialPort1_PinChanged(object sender, SerialPinChangedEventArgs e)
        {

        }

        private void button_Send_Click(object sender, EventArgs e)
        {

        }

        private void toolStripButton_clear_Click(object sender, EventArgs e)
        {
            richTextBox_Receive.Clear();
        }

        /// <summary>
        /// 发送前校验
        /// </summary>
        /// <returns></returns>
        private bool beforeSendValidate()
        {
            if (!serialPort1.IsOpen)
            {
                if (MessageBox.Show("串口未打开，确定打开串口吗？", "温馨提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
                {
                    button_OpenPort.PerformClick();
                }
                return false;
            }
            if (richTextBox_send.Text == null || string.IsNullOrEmpty(richTextBox_send.Text.Trim()))
            {
                MessageBox.Show("发送内容不能为空！", "温馨提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }
            return true;
        }
        private void toolStripButton2_Click(object sender, EventArgs e)
        {

        }

        private void radioButton_hex_CheckedChanged(object sender, EventArgs e)
        {
            if (richTextBox_send.Text.Length == 0 || string.IsNullOrWhiteSpace(richTextBox_send.Text))
            {
                return;
            }
            if (toolStripButton_ASCII.Checked)
            {
                richTextBox_send.Text = ASCIIEncoding.Default.GetString(CommonHelper.StrToHex(richTextBox_send.Text));

            }
            else
            {
                richTextBox_send.Text = BitConverter.ToString(ASCIIEncoding.Default.GetBytes(
                      richTextBox_send.Text));
            }
        }

        /// <summary>
        /// 发送按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton_send_Click(object sender, EventArgs e)
        {
            if (!beforeSendValidate())
            {
                return;
            }
            sendData();
        }

        /// <summary>
        /// 发送数据
        /// </summary>
        private void sendData()
        {
            if (!serialPort1.IsOpen)
            {
                return;
            }


            if (toolStripButton_ASCII.Checked)
            {
                serialPort1.Write(richTextBox_send.Text);
                SEND_BYTES += richTextBox_send.Text.Length;
            }
            else
            {//HEX格式转换 
                byte[] sendBuf = CommonHelper.StrToHex(richTextBox_send.Text);
                serialPort1.Write(sendBuf, 0, sendBuf.Length);
                SEND_BYTES += sendBuf.Length;
            }
        }

        private void toolStripStatusLabel3_Click(object sender, EventArgs e)
        {
            //打开网站链接
            //调用系统默认的浏览器 
            System.Diagnostics.Process.Start("http://www.posoft.cn");
        }

        private void comboBox_portName_SelectionChangeCommitted(object sender, EventArgs e)
        {
            OpenSerialPort();
        }

        private void toolStripButton_showTime_CheckStateChanged(object sender, EventArgs e)
        {
            if (toolStripButton_showTime.Checked)
            {
                toolStripButton_showTime.Image = Properties.Resources.chkGreenOn;
            }
            else
            {
                toolStripButton_showTime.Image = Properties.Resources.chkGreenOff;
            }
        }

        private void toolStripButton_HexMod_CheckStateChanged(object sender, EventArgs e)
        {
            if (toolStripButton_HexMod.Checked)
            {
                toolStripButton_HexMod.Image = Properties.Resources.chkGreenOn;
            }
            else
            {
                toolStripButton_HexMod.Image = Properties.Resources.chkGreenOff;
            }
        }

        private void toolStripButton_pause_CheckStateChanged(object sender, EventArgs e)
        {
            if (toolStripButton_pause.Checked)
            {
                toolStripButton_pause.Image = Properties.Resources.start;
                richTextBox_Receive.BackColor = Color.LightGray;
                toolStripButton_pause.Text = "继续接收";
            }
            else
            {
                toolStripButton_pause.Image = Properties.Resources.pause;
                richTextBox_Receive.BackColor = Color.White;
                toolStripButton_pause.Text = "暂停接收";
            }
        }

        private void toolStripButton_sentTimes_CheckStateChanged(object sender, EventArgs e)
        {
            if (toolStripButton_sentTimes.Text == null || string.IsNullOrWhiteSpace(toolStripButton_sentTimes.Text))
            {
                MessageBox.Show("请先设置发送周期！", "温馨提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                //toolStripButton_sentTimes.Checked = false;
                return;
            }
            if (toolStripButton_sentTimes.Checked)
            {
                if (!beforeSendValidate())
                {

                    return;
                }
                int tik = 1000;
                if (!int.TryParse(toolStripComboBox_sendTimes.Text, out tik))
                {
                    toolStripComboBox_sendTimes.Text = "1000";
                }
                if (tik <= 0)
                {
                    tik = 1;
                }
                timer.Interval = tik;
                timer.Start();
                toolStripButton_sentTimes.Image = Properties.Resources.chkGreenOn;
            }
            else
            {
                timer.Stop();
                toolStripButton_sentTimes.Image = Properties.Resources.chkGreenOff;
            }
        }

        private void toolStripButton_sentTimes_Click(object sender, EventArgs e)
        {

        }

        private void toolStripComboBox_sendTimes_TextChanged(object sender, EventArgs e)
        {
            int tik = 1000;
            if (!int.TryParse(toolStripComboBox_sendTimes.Text, out tik))
            {
                toolStripComboBox_sendTimes.Text = "1000";
            }
            if (tik <= 0)
            {
                tik = 1;
            }
            timer.Interval = tik;
        }

        private void toolStripButton_Hex_CheckStateChanged(object sender, EventArgs e)
        {
            toolStripButton_ASCII.Checked = !toolStripButton_Hex.Checked;
            if (toolStripButton_Hex.Checked)
            {
                toolStripButton_Hex.Image = Properties.Resources.radioOn;
            }
            else
            {
                toolStripButton_Hex.Image = Properties.Resources.radioOff;
            }

            if (richTextBox_send.Text.Length == 0 || string.IsNullOrWhiteSpace(richTextBox_send.Text))
            {
                return;
            }

            if (toolStripButton_Hex.Checked)
            {
                richTextBox_send.Text = BitConverter.ToString(ASCIIEncoding.Default.GetBytes(
                     richTextBox_send.Text)).Replace('-', ' ');
            }
            else
            {
                richTextBox_send.Text = ASCIIEncoding.Default.GetString(CommonHelper.StrToHex(richTextBox_send.Text));
            }
        }

        private void toolStripButton_ASCII_CheckStateChanged(object sender, EventArgs e)
        {
            toolStripButton_Hex.Checked = !toolStripButton_ASCII.Checked;
            if (toolStripButton_ASCII.Checked)
            {
                toolStripButton_ASCII.Image = Properties.Resources.radioOn;
            }
            else
            {
                toolStripButton_ASCII.Image = Properties.Resources.radioOff;
            }
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            richTextBox_send.Clear();
        }

        private void toolStripStatusLabel3_Click_1(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.posoft.cn/");
        }

        private void button_ToolsCalc_Click(object sender, EventArgs e)
        {
            System.Diagnostics.ProcessStartInfo Info = new System.Diagnostics.ProcessStartInfo();
            Info.FileName = "calc.exe ";//"calc.exe"为计算器，"notepad.exe"为记事本
            System.Diagnostics.Process Proc = System.Diagnostics.Process.Start(Info);
        }

        private void radMultiColumnComboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //List<SendDataLog> objList = radMultiColumnComboBox1.DataSource as List<SendDataLog>;

            //if (objList == null || objList.Count == 0 || objList.Count <= radMultiColumnComboBox1.SelectedIndex)
            //{
            //    return;
            //}
            //if (radMultiColumnComboBox1.SelectedIndex < 0)
            //    return;

            //SendDataLog obj = objList[radMultiColumnComboBox1.SelectedIndex];
            //if (obj.Send_mode.Equals(SEND_MODE.ASCII.ToString()))// == 1)
            //{
            //    toolStripButton_ASCII.Checked = true;
            //}
            //else
            //{
            //    toolStripButton_Hex.Checked = true;
            //}
            //richTextBox_send.Text = obj.Send_data_content;
            if (radMultiColumnComboBox1.SelectedItem == null)
            {
                return;
            }
            //DataTable tbl = radMultiColumnComboBox1.DataSource as DataTable;

            //if (tbl == null || tbl.Rows.Count == 0 || tbl.Rows.Count <= radMultiColumnComboBox1.SelectedIndex)
            //{
            //    return;
            //}
            //if (radMultiColumnComboBox1.SelectedIndex < 0)
            //{
            //    return;
            //}

            GridViewDataRowInfo rw = radMultiColumnComboBox1.SelectedItem as GridViewDataRowInfo;

           
            if ( SEND_MODE.ASCII.ToString().Equals(rw.Cells["模式"].Value))
            {
                toolStripButton_ASCII.Checked = true;
            }
            else
            {
                toolStripButton_Hex.Checked = true;
            }
            richTextBox_send.Text = rw.Cells["发送内容"].Value as string;

        }

        private void 保存SToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrWhiteSpace(richTextBox_send.Text))
            {
                MessageBox.Show("内容为空不能保存！");
                return;
            }
            SendDataLog obj = new SendDataLog();
            obj.Send_data_content = richTextBox_send.Text;
            obj.Send_mode = toolStripButton_Hex.Checked ? SEND_MODE.HEX.ToString() : SEND_MODE.ASCII.ToString();
            SaveCmd scFrm = new SaveCmd(obj);
            scFrm.OnSavedSendDataLog += ScFrm_OnSavedSendDataLog;
            scFrm.ShowDialog(this);            
        }

        private void ScFrm_OnSavedSendDataLog(SendDataLog obj)
        {
            initMultiColumnComboBoxData();
        }

        private void toolStripButton_EditCmd_Click(object sender, EventArgs e)
        {
            EditCmd eFrm = new EditCmd();
            eFrm.ShowDialog(this);
        }

    }
}
